package org.bigtree.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bigtree.example.common.utils.PredicateUtils;
import org.bigtree.example.common.webapi.PageResult;
import org.bigtree.example.constans.ResponseCode;
import org.bigtree.example.entity.Employ;
import org.bigtree.example.mapper.EmployMapper;
import org.bigtree.example.model.form.EmployForm;
import org.bigtree.example.model.form.EmploySearchForm;
import org.bigtree.example.model.vo.EmployVo;
import org.bigtree.example.service.IEmployService;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author bigTree
 * @since 2025/4/26
 */
@Slf4j
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "db-cache")
public class EmployServiceImpl extends ServiceImpl<EmployMapper, Employ> implements IEmployService {
    private final EmployMapper employMapper;

    @CachePut(key = "#result.id", unless = "#result == null")
    @Override
    public EmployVo create(EmployForm form) {
        Employ entity = form.toEntity();
        PredicateUtils.orElseThrow(this.save(entity), ResponseCode.SAVE_FAILED);
        return EmployVo.of(entity);
    }

    @CachePut(key = "#id", unless = "#result == null")
    @Override
    public EmployVo edit(Long id, EmployForm form) {
        Employ entity = form.toEntity();
        entity.setId(id);
        PredicateUtils.orElseThrow(this.updateById(entity), ResponseCode.UPDATE_FAILED);
        return EmployVo.of(entity);
    }

    @CacheEvict(key = "#id", beforeInvocation = true)
    @Override
    public void remove(Long id) {
        PredicateUtils.orElseThrow(this.removeById(id), ResponseCode.REMOVE_FAILED);
    }

    @Cacheable(key = "#id", unless = "#result == null")
    @Override
    public EmployVo detail(Long id) {
        return EmployVo.of(this.getById(id));
    }

    @Override
    public PageResult<EmployVo> all(EmploySearchForm form) {
        LambdaQueryWrapper<Employ> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Objects.nonNull(form.getName()), Employ::getName, form.getName());
        wrapper.like(Objects.nonNull(form.getAddress()), Employ::getAddress, form.getAddress());
        wrapper.ge(Objects.nonNull(form.getStartDate()), Employ::getBirthday, form.getStartDate());
        wrapper.le(Objects.nonNull(form.getEndDate()), Employ::getBirthday, form.getEndDate());
        wrapper.orderByDesc(Employ::getUpdateTime);
        Page<Employ> reqPage = Page.of(form.getPageNo(), form.getPageSize());
        Page<Employ> page = this.page(reqPage, wrapper);
        return PageResult.of(page, EmployVo::of);
    }
}
